/* TourApp.Java
 * 
 * This class supervises the application and holds
 * references to the resources essential to it.
 *  
 * Greg Warner
 * Derek Dupuis
 * Michael Dixey
 * Alex Schwartz
 */

import java.util.*;

public class TourApp
{
   private Cmd cmd;
   private String commandLine;
   private Scanner sc;
   private String[ ] token;
   
   //data structures ( Collection Classes ) go here
   private TourColl tourColl;
   private TourOffColl tourOffColl;
   private ProviderColl providerColl;
   private ServiceColl serviceColl;
   
   /** This constructor initializes the collection
     * of objects( DATA STRUCTURES WE NEED ) and accepts the input stream
     * include global appreciation rates here too
     */
   public TourApp( Scanner s )
   {
      sc = s;
      //initialize any variables you need here
      
      tourColl = new TourColl();
      tourOffColl = new TourOffColl();
      providerColl = new ProviderColl();
      serviceColl = new ServiceColl();
      
      // create 4 default services and add them to the service collection
      Service service = new Service( "travel" );
      serviceColl.add( service );
      service = new Service( "lodging" );
      serviceColl.add( service );
      service = new Service( "activity" );
      serviceColl.add( service );
      service = new Service( "food" );
      serviceColl.add( service );
   }
   
   /* schedule( )
    *  implements the scheduling policies
    */
   public void schedule( TourOff t )
   {
      ScheduleIF scheduler = new SchedulerD();
      if( scheduler.schedule( this, t ) )
         System.out.printf( " Tour Scheduled with D.\n" );
      else
      {
         scheduler = new SchedulerC();
         if( scheduler.schedule( this, t ) )
            System.out.printf( " Tour Scheduled with C.\n" );
         else
         {
            scheduler = new SchedulerA();
            if( scheduler.schedule( this, t ) )
               System.out.printf( " Tour Scheduled with A.\n" );
            else
               System.out.printf( "Tour NOT Scheduled!\n" );
         }
      }
   }
   
   /* processCMDs( )
    *  invoke med app to process commands
    */
   public void processCMDs( )
   {
      while( sc.hasNext( ) )
      {
         
         commandLine = sc.nextLine( ).trim( );
         
         if( commandLine.length( ) > 0 )
         {
            token = commandLine.trim( ).split( "\\s*:\\s*" );
            
            // break commands into tokens, use first token to id command name
            
            // if the first character is '#', echo the line to output
            // without processing any commands
            if( token[ 0 ].charAt( 0 ) == '#' )
            {
               System.out.println( commandLine );
            }
            else
            {
               // convert to lower case
               for( int k = 0; k < token.length; k++ )
                  token[k] = token[k].toLowerCase();
               
               //indentify the command, pass it the tokens, invoke its execute method
               cmd = Cmd.findCmd( token[ 0 ] );
               
               if( cmd != null )
               {
                  cmd.tourApp( this );
                  cmd.token( token );
                  cmd.exec( );
               }
               else
                  System.out.printf( "--command not recognized\n" );
            }
         }
      }
      System.out.println( "\n----------*****No more commands*****----------\n" );
      
      //Processing Commands Complete* * * * * * * * * * * * * * * * * /
      
      Set t = tourOffColl.keySet();
      Iterator iter = t.iterator();
      while( iter.hasNext() )
         tourOffColl.get( iter.next() ).match( );
      
      iter = t.iterator();
      while( iter.hasNext() )
         schedule( tourOffColl.get( iter.next() ) );
      
      
      System.out.print( "\n"+tourColl.toString() );
      System.out.print( tourOffColl.toString() );
      
      iter = t.iterator();
      while( iter.hasNext() )
      {
         Object temp = iter.next();
         System.out.println( "Traveler's Itinerary for: " +
                            tourOffColl.get( temp ).offeringName() );
         System.out.print( tourOffColl.get( temp ).printTravelPlans() + "\n" );
      }
      //--ends
   }
   
   //add and get for tourCollection
   public boolean addTour( Tour t )
   {
      return tourColl.add( t );
   }
   
   public Tour getTour( String s )
   {
      return tourColl.get( s );
   }   
   
   //add and get for tourOfferingCollection
   public boolean addTourOffering( TourOff tO )
   {
      return tourOffColl.add( tO );
   }
   
   public TourOff getTourOffering( String s )
   {
      return tourOffColl.get( s );
   }
   
   //add and get for serviceCollection
   public boolean addService( Service s )
   {       
      return serviceColl.add( s );
   }
   
   public Service getService( String s )
   {
      return serviceColl.get( s );
   }
   
   // added find to verify existing service from ProviderCMD
   public boolean findService( String s )
   {
      return serviceColl.find( s );
   }
   
   //add and get for providerCollection
   public boolean addProvider( Provider p )
   {
      return providerColl.add( p );
   }
   
   public Provider getProvider( String s )
   {
      return providerColl.get( s );
   }
   
   public ProviderColl providers() { return providerColl; }
}

